# -*- coding: utf-8 -*-
import frappe
from frappe.model.document import Document
from frappe.utils import flt, cint, nowdate, nowtime, get_datetime, format_datetime
from frappe.permissions import add_permission

class ScrapPickupList(Document):
    """
    余料待取清单控制器
    处理余料待取清单的数据验证和业务逻辑
    """
    
    def validate(self):
        """验证数据有效性"""
        self.validate_pickup_list_id()
        self.validate_warehouse()
        self.validate_scrap_materials()
        self.set_pickup_date()
        self.set_created_info()
    
    def validate_pickup_list_id(self):
        """验证待取清单编号唯一性"""
        if not self.pickup_list_id:
            self.pickup_list_id = self.generate_pickup_list_id()
            return
        
        # 检查编号唯一性
        if frappe.db.exists("Scrap Pickup List", {"pickup_list_id": self.pickup_list_id, "name": ["!=", self.name]}):
            frappe.throw(f"待取清单编号 {self.pickup_list_id} 已存在，请使用其他编号")
    
    def generate_pickup_list_id(self):
        """生成待取清单编号"""
        # 格式: SPL-YYYYMMDD-NNNN
        from frappe.model.naming import make_autoname
        return make_autoname("SPL-.YYYYMMDD-.#####")
    
    def validate_warehouse(self):
        """验证仓库有效性"""
        if not self.warehouse:
            frappe.throw("请选择仓库")
        
        # 检查仓库是否存在
        if not frappe.db.exists("Scrap Warehouse", self.warehouse):
            frappe.throw(f"仓库 {self.warehouse} 不存在")
        
        # 检查仓库状态
        warehouse_status = frappe.db.get_value("Scrap Warehouse", self.warehouse, "status")
        if warehouse_status != "启用":
            frappe.throw(f"仓库 {self.warehouse} 状态为 {warehouse_status}，无法使用")
    
    def validate_scrap_materials(self):
        """验证余料列表"""
        if not self.scrap_materials or len(self.scrap_materials) == 0:
            frappe.throw("请添加至少一项余料")
        
        # 验证每个余料项
        for item in self.scrap_materials:
            if not item.scrap_material:
                frappe.throw("请选择余料")
            
            if not item.location:
                frappe.throw("请选择库位")
            
            if not item.quantity or flt(item.quantity) <= 0:
                frappe.throw("数量必须大于0")
            
            # 检查余料状态
            scrap_material_status = frappe.db.get_value("Scrap Material", item.scrap_material, "status")
            if scrap_material_status != "可用":
                frappe.throw(f"余料 {item.scrap_material} 状态为 {scrap_material_status}，无法添加到待取清单")
            
            # 检查余料是否在指定库位
            scrap_material_location = frappe.db.get_value("Scrap Material", item.scrap_material, "location")
            if scrap_material_location != item.location:
                frappe.throw(f"余料 {item.scrap_material} 不在库位 {item.location} 中")
            
            # 检查数量是否超过可用数量
            available_quantity = frappe.db.get_value("Scrap Material", item.scrap_material, "quantity")
            if flt(item.quantity) > flt(available_quantity):
                frappe.throw(f"余料 {item.scrap_material} 数量 {item.quantity} 超过可用数量 {available_quantity}")
    
    def set_pickup_date(self):
        """设置待取日期"""
        if not self.pickup_date:
            self.pickup_date = nowdate()
    
    def set_created_info(self):
        """设置创建信息"""
        if not self.created_by:
            self.created_by = frappe.session.user
            self.created_date = get_datetime()
    
    def before_submit(self):
        """提交前处理"""
        # 设置状态信息
        if self.status == "已取":
            self.picked_by = frappe.session.user
            self.picked_date = get_datetime()
        elif self.status == "已完成":
            self.completed_by = frappe.session.user
            self.completed_date = get_datetime()
    
    def on_submit(self):
        """提交后处理"""
        # 创建事务记录
        self.create_pickup_transaction()
    
    def before_cancel(self):
        """取消前处理"""
        # 检查是否可以取消
        if self.status not in ["待取", "已取"]:
            frappe.throw(f"状态为 {self.status} 的待取清单无法取消")
    
    def on_cancel(self):
        """取消后处理"""
        # 创建取消事务记录
        self.create_cancel_transaction()
    
    def create_pickup_transaction(self):
        """创建取料事务记录"""
        for item in self.scrap_materials:
            doc = frappe.new_doc("Scrap Transaction")
            doc.transaction_type = "待取"
            doc.transaction_date = self.pickup_date
            doc.scrap_material = item.scrap_material
            doc.warehouse = self.warehouse
            doc.location = item.location
            doc.quantity = item.quantity
            doc.reference_doctype = "Scrap Pickup List"
            doc.reference_name = self.name
            doc.notes = f"待取清单 {self.pickup_list_id} 待取"
            doc.insert(ignore_permissions=True)
    
    def create_cancel_transaction(self):
        """创建取消事务记录"""
        for item in self.scrap_materials:
            doc = frappe.new_doc("Scrap Transaction")
            doc.transaction_type = "取消待取"
            doc.transaction_date = nowdate()
            doc.scrap_material = item.scrap_material
            doc.warehouse = self.warehouse
            doc.location = item.location
            doc.quantity = item.quantity
            doc.reference_doctype = "Scrap Pickup List"
            doc.reference_name = self.name
            doc.notes = f"取消待取清单 {self.pickup_list_id}"
            doc.insert(ignore_permissions=True)
    
    def calculate_total_quantity(self):
        """计算总数量"""
        total_quantity = 0
        for item in self.scrap_materials:
            total_quantity += flt(item.quantity)
        self.total_quantity = total_quantity
    
    def mark_as_picked(self):
        """标记为已取"""
        if self.status != "待取":
            frappe.throw("只有待取状态的清单才能标记为已取")
        
        self.status = "已取"
        self.picked_by = frappe.session.user
        self.picked_date = get_datetime()
        self.save()
        
        # 更新子表项状态
        for item in self.scrap_materials:
            if item.status == "待取":
                item_doc = frappe.get_doc("Scrap Pickup List Item", item.name)
                item_doc.mark_as_picked()
        
        return True
    
    def mark_as_completed(self):
        """标记为已完成"""
        if self.status != "已取":
            frappe.throw("只有已取状态的清单才能标记为已完成")
        
        # 检查是否所有项都已取
        for item in self.scrap_materials:
            if item.status != "已取":
                frappe.throw("还有未取的余料，无法标记为已完成")
        
        self.status = "已完成"
        self.completed_by = frappe.session.user
        self.completed_date = get_datetime()
        self.save()
        
        return True
    
    def reset_to_pending(self):
        """重置为待取状态"""
        self.status = "待取"
        self.picked_by = ""
        self.picked_date = ""
        self.completed_by = ""
        self.completed_date = ""
        self.save()
        
        # 重置子表项状态
        for item in self.scrap_materials:
            if item.status == "已取":
                item_doc = frappe.get_doc("Scrap Pickup List Item", item.name)
                item_doc.reset_to_pending()
        
        return True
    
    @frappe.whitelist()
    def get_pickup_list_list(self, status=None, warehouse=None, from_date=None, to_date=None):
        """获取待取清单列表"""
        filters = {}
        
        if status:
            filters["status"] = status
        if warehouse:
            filters["warehouse"] = warehouse
        if from_date:
            filters["pickup_date"] = [">=", from_date]
        if to_date:
            filters["pickup_date"] = ["<=", to_date]
        
        return frappe.db.get_all("Scrap Pickup List",
            filters=filters,
            fields=["name", "pickup_list_id", "pickup_date", "warehouse", "priority", "status", "total_quantity"],
            order_by="pickup_date desc"
        )
    
    @frappe.whitelist()
    def get_pending_pickup_lists(self):
        """获取待取的清单"""
        return frappe.db.get_all("Scrap Pickup List",
            filters={"status": "待取"},
            fields=["name", "pickup_list_id", "pickup_date", "warehouse", "priority", "created_by", "created_date"],
            order_by="priority desc, pickup_date asc"
        )
    
    @frappe.whitelist()
    def get_picked_pickup_lists(self):
        """获取已取的清单"""
        return frappe.db.get_all("Scrap Pickup List",
            filters={"status": "已取"},
            fields=["name", "pickup_list_id", "pickup_date", "warehouse", "priority", "picked_by", "picked_date"],
            order_by="picked_date desc"
        )